# -*- coding: utf-8 -*-

from pyparsing import *
from myparse import *

def isnum(s):
    # 12.34E+56
    return matchString(num, s)

CMD1 = iden + Optional(asign.suppress() + (num | iden)) | (Literal('@').suppress() + num).setResultsName('refer')

CMD2 = (Literal('clear') | Literal('history') | Literal('context')).setResultsName('meta')

CMD = CMD2 | CMD1

def process(pr, ctxt={}):
    if 'meta' in pr:
        if pr[0] == 'quit':
            print('game over')
            exit()
        elif pr[0] == 'clear':
            ctxt={}
        elif pr[0] == 'history':
            print(history)
        elif pr[0] == 'context':
            print(context)
        return None, ctxt
    else:
        if len(pr)==1:
            if pr[0] in ctxt:
                val=ctxt[pr[0]]
            else:
                val=None
        else:
            val = pr[1]
            if isnum(val):
                ctxt.update({pr[0]:val})
            elif val in ctxt:
                val = ctxt[val]
                ctxt.update({pr[0]:val})
            else:
                ctxt.update({pr[0]:None})
        return val, ctxt

context = {}
history = []
k=0
while True:
    cmd=input('[%d]: '%k)        # import command (as a string)
    pr=CMD.parseString(cmd)       # parsing
    if 'refer' in pr:             # refering to command in history
        cmd=history[int(pr[0])]
        pr=CMD.parseString(cmd)   # parsing
        print('repeat', cmd)
    try:
        val, context = process(pr, context) # process the parsing result
        if val != None:
            print(val)
    except Exception as ex:
        print(ex)
    history.append(cmd)
    k+=1
